【FreeRTOS】详细讲解FreeRTOS中事件(event)并通过具体示例讲述其用法

您所在的位置:网站首页 freertos 调度 【FreeRTOS】详细讲解FreeRTOS中事件(event)并通过具体示例讲述其用法

【FreeRTOS】详细讲解FreeRTOS中事件(event)并通过具体示例讲述其用法

2024-07-12 16:26:21| 来源: 网络整理| 查看: 265

文章目录 事件函数解析示例

事件

  事件,实际上是一种任务间通信的机制,主要用于实现多任务间的同步,其只能是事件类型的通信,无数据传输。与信号量不同的是,它可以实现一对多,多对多的同步。即可以是任意一个事件发生时唤醒任务进行事件处理;也可以是几个事件都发生后才唤醒任务进行事件处理;同样,也可以是多个任务同步多个事件。   FreeRTOS中任务可以通过设置事件位来实现事件的触发和等待操作。但FreeRTOS的事件仅用于同步,不提供数据传输功能,其具有如下特点:

事件只与任务相关联,事件相互独立,一个32位的事件集合(EventBits_t类型的变量,实际可用与表示事件的只有24位),用于标识该任务发生的事件类型,其中每一位表示一种事件类型(0表示该事件类型未发生、1表示该事件类型已经发生),一共24种事件类型;事件仅用于同步,不提供数据传输功能;事件无排队性,即多次向任务设置同一事件(如果任务还未来得及读走),等效于只设置一次;允许多任务对同一事件进行读写操作;支持事件等待超时机制。

应用

  事件在一定程度上可以代替信号量,用于任务与任务间、中断与任务间同步。   与信号量不同之处在于,事件是不可累计的,而信号量是可累计。并且,一个任务使用事件同步时,可以等待多个事件产生才进行同步;而信号量是单一的同步操作,只能与一个中断或任务同步,无法与多个中断或任务同步。

事件运行机制示意图

  实际使用事件相关函数前,需要将configSUPPORT DYNAMIC ALLOCATION置1。

函数解析

前奏

定义事件控制权柄所用的EventGroupHandle_t其实是一个结构体指针,其声明为typedef struct EventGroupDef_t * EventGroupHandle_t。事件控制块EventGroup_t,内部最多含有四个变量,其中两个变量uxEventBits与xTasksWaitingForBits是一直可使用,但变量uxEventGroupNumber与ucStaticallyAllocated收到FreeRTOS配置管理 typedef struct EventGroupDef_t { EventBits_t uxEventBits; List_t xTasksWaitingForBits; #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxEventGroupNumber; #endif #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) \ && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) uint8_t ucStaticallyAllocated; #endif } EventGroup_t;

   EventBits_t:事件标志组存储在EventBits_t 类型的变量中。    若FreeRTOS配置时,将configUSE_16_BIT_TICKS定义为1,那么EventBits_t就为16位,其中只有8位存储时间组;否则,若configUSE_16_BIT_TICKS定义为0,那么EventBits_t就为32位,其中24位存储事件组。每一位代表一个事件是否发生(事件发生为1,否则为0)。倘若兄弟认为8位或24位事件组不够用,还可以使用与或非等逻辑运算来组成更多事件。🤣🤣🤣    xTasksWaitingForBits:该变量是一个列表,内部存储等待此事件的所有任务。    uxEventGroupNumber:记录事件组数量。    ucStaticallyAllocated:记录时间组分配方式,如果事件组是静态分配的,则设置为 pdTRUE,以确保不尝试释放内存。

动态创建事件

原函数

EventGroupHandle_t xEventGroupCreate( void );

参数解析

返回值:类型为EventGroupHandle_t,其为事件的控制权柄。

函数说明   动态创建一个事件。

静态创建事件

原函数

EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer );

参数解析

StaticEventGroup_t * pxEventGroupBuffer:为事件组分配的空间;返回值:类型为EventGroupHandle_t,其为事件的控制权柄

函数说明    静态创建事件组,创建时需要传入存储空间。

创建事件

原函数

void vEventGroupDelete( EventGroupHandle_t xEventGroup );

参数解析

EventGroupHandle_t xEventGroup:传入事件组控制权柄;

函数说明  &esnp;删除事件组,只要将事件组控制权柄传入即可。删除只能删除已经创建成功的事件组。

事件触发

原函数

EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );

参数解析

EventGroupHandle_t xEventGroup:事件组的控制权柄;const EventBits_t uxBitsToSet:需要触发事件的,也就是其在事件组的位置;返回值:返回函数操作的事件组的值;

函数说明   触发事件组中某个事件(事件对应事件组的位置),其位置由uxBitsToSet的值决定。   该函数内部有判断机制,即的判断该事件是否创建,只有事件组创建成功以及操作位有效,该函数才能正常运作。

中断中唤醒事件

原函数

BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t * pxHigherPriorityTaskWoken );

参数解析

EventGroupHandle_t xEventGroup:事件组的操作句柄;const EventBits_t uxBitsToSet:需要触发事件的,也就是其在事件组的位置;BaseType_t * pxHigherPriorityTaskWoken:在使用之前必须初始化成pdFALSE;返回值:类型为BaseType_t。若其值为pdFalse,则消息已经发送成功;否则,发送失败。

函数说明   是xEventGroupSetBits函数的中断版,其功能是中断中唤醒某个事件。

等待事件唤醒

原函数

EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait );

参数解析

EventGroupHandle_t xEventGroup:事件的操作句柄;const EventBits_t uxBitsToWaitFor:等待的事件,这里可以是多个事件,使用或运算即可连接;const BaseType_t xClearOnExit:当其值为pdTRUE时,一旦监测到匹配的事件,系统就会将删除由该事件引起的标志位;否则,当其值为pdFALSE时,将删除标志位;const BaseType_t xWaitForAllBits:当其值为pdTURE时,相应的uxBitsToWaitFor中多个事件应该使用&连接;否则当其值为pdFALSE时,uxBitsToWaitFor中多个事件应该使用|连接。这样函数返回值才是对应标志位的值,事件才能够触发。TickType_t xTicksToWait:最大超时时间,单位为系统节拍时间,使用portMAX_DELAY即相当于一直阻塞;返回值:类型为EventBits_t,返回事件中事件标志位,但是返回值很可能并不是用户指定的事件位,需要再进行判断再处理。

函数说明   xEventGroupWaitBits函数的作用是等待事件触发。若需要等待的事件一直未触发,函数就会阻塞,阻塞时间为最大超时时间xTicksToWait。

清除事件标志位

原函数

EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );

参数解析

EventGroupHandle_t xEventGroup:事件组操作句柄;const EventBits_t uxBitsToClear:时间组中需要清除的位置;返回值:类型EventBits_t,返回事件清除前的值;

函数说明   清除事件组中对应位置的标志位。在获取事件时对应标志位未擦除,那么可以使用该函数做显示擦除。

中断中清除事件标志位

原函数

BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );

参数解析

EventGroupHandle_t xEventGroup:事件组操作句柄;const EventBits_t uxBitsToClear:时间组中需要清除的位置;返回值:类型EventBits_t,返回事件清除前的值;

函数说明   是函数xEventGroupClearBits的中断版,功能上与之一样。

示例

  声明8个事件,并且创建一个FreeRTOS事件,用于任务同步,再创建两个任务。完成:任务1,等待事件触发,7个事件中触发一个事件后反转对应LED的状态,当事件8触发时,统计其触发次数并且显示到LCD屏上; 任务2,每个1s发送一个事件触发请求,并且反转LED8的状态。

核心源码

//任务控制权柄 TaskHandle_t xHandleTsak[2]; // 事件控制权柄 EventGroupHandle_t myxEventGroupHandle_t = NULL; // 声明事件 #define EVENT1 (0x01 // 设置变量接收事件 EventBits_t r_event; // 保存LED的状态 int ledState[] = {0,0,0,0,0,0,0}; // 记录LED的位置 uint16_t ledLocation[] = {LED1,LED2,LED3,LED4,LED5,LED6,LED7}; // 记录EVENT8触发次数 uint16_t eventTriggerCount = 0; // 保存显示到LCD中的数据 char temp[30]; // 用于循环 int i = 0; while(1) { //阻塞等待8个事件中任意一个事件 r_event = xEventGroupWaitBits(myxEventGroupHandle_t,EVENT1|EVENT2|EVENT3|EVENT4|EVENT5|EVENT6|EVENT7|EVENT8, pdTRUE,pdFALSE,portMAX_DELAY); //判断事件类型 if((r_event&EVENT1) !=0) ++ledState[0]; else if((r_event&EVENT2) !=0) ++ledState[1]; else if((r_event&EVENT3) !=0) ++ledState[2]; else if((r_event&EVENT4) !=0) ++ledState[3]; else if((r_event&EVENT5) !=0) ++ledState[4]; else if((r_event&EVENT6) !=0) ++ledState[5]; else if((r_event&EVENT7) !=0) ++ledState[6]; else { sprintf(temp," Event8 count:%d",++eventTriggerCount); LCD_DisplayStringLine(Line4,(uint8_t*)temp); changeAllLedByStateNumber(OFF); } // 设置每个LED灯状态 for(i=0;iEVENT1,EVENT2,EVENT3,EVENT4,EVENT5,EVENT6,EVENT7,EVENT8}; int i = -1; // 保存系统时间 static portTickType myPreviousWakeTime; // 保存阻塞时间 const volatile TickType_t xDelay1000ms = pdMS_TO_TICKS( 1000UL ); // 获取当前时间 myPreviousWakeTime = xTaskGetTickCount(); while(1) { // 每次执行都翻转LED8状态 以保证肉眼看到该任务在运行 rollbackLedByLocation(LED8); // 发送事件同步 xEventGroupSetBits(myxEventGroupHandle_t,event[++i%8]); // 非阻塞延时1s xTaskDelayUntil( &myPreviousWakeTime,xDelay1000ms ); } }

结果

事件测试结果图

  小编也有其他的一些相关文章,欢迎各位看官点击观看😉😉😉

【FreeRTOS】详细讲解FreeRTOS中任务管理并通过示例讲述其用法【FreeRTOS】详细讲解FreeRTOS的软件定时器及通过示例讲述其用法【FreeRTOS】详细讲解FreeRTOS中消息队列并通过示例讲述其用法 最后 ,欢迎大家留言或私信交流,共同进步!😁😁😁


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭